<?php

/*
 * 队列的最大限度取决于 memory_limit 因为所有的数据从队列返回出去都是使用的变量，如果是迭代器的话，可以基本无限制容量的队列
 * 如果需要使用很大长度的队列请修改 memory_limit的大小
 * 
 */

final class queue {

    public static $queue;
    public static $instance;

    public function __construct() {

        if (empty(self::$instance)) {
            self::$queue = new \SplQueue();
            self::$instance = \spl_object_hash(self::$queue);
        } else {
            if (self::$instance == \spl_object_hash(self::$queue)) {
                throw new \Exception("Queue service cannot be created multiple times");
            }
        }
        return self::$queue;
    }

    //压入队列 
    public function push($work) {
        if (empty($this->get_queue()) || $this->get_queue() instanceof queue) {
            throw new \Exception('Queue service not created');
        }
        $this->get_queue()->push($work);
    }

    //压出 队列 最后一个
    public function pop() {
        if (empty($this->get_queue()) || $this->get_queue() instanceof queue) {
            throw new \Exception('Queue service not created');
        }
        $this->get_queue()->pop();
    }

    //压出 队列 根据work名称
    public function pop_by_work($work) {
        self::get_queue()::pop($work);
    }

    //分发任务
    public function distribution_task($work) {
        $queue = $this->get_queue();
        //异步分发一次取20个
        $task = array();

        for ($i = 1; $i < 20; $i++) {
            $task;
            $fp = fsockopen('localhost', 80, &$errno, &$errstr, 5);
            if (!$fp) {
                echo "$errstr ($errno)<br />\n";
            }
            fputs($fp, "GET /work.php?data=1\r\n"); #请求的资源 URL 一定要写对
            fclose($fp);
        }
    }

    public function output() {
        echo '<pre>';
        print_r(self::$queue);
        echo '<pre>';
    }

    //获取整个 队列
    public function get_queue() {
        return self::$queue;
    }

    public function reset_queue() {
        $this->get_queue()->valid();
    }

    public function get_queue_array() {
        if ($this->get_queue() instanceof queue) {
            throw new \Exception('Queue service not created');
        }
        $array = [];
        //reset array index
        $this->reset_queue();
        foreach ($this->get_queue() as $k => $v) {
            $array[] = $v;
        }
        return $array;
    }

    public function get_queue_iterator() {
        if ($this->get_queue() instanceof queue) {
            throw new \Exception('Queue service not created');
        }
        //reset array index
        $this->reset_queue();
        foreach ($this->get_queue() as $k => $v) {
            yield $k => $v;
        }
    }

    public function count_queue() {
        return count(self::$queue);
    }

    public static function __callStatic($func, $arguments) {
        throw new \Exception("Static method {$func} does not exist");
    }

    public function __call($func, $arguments) {
        throw new \Exception("method {$func} does not exist");
    }

    public function __destruct() {
        
    }

    public function __invoke() {
        
    }

    private function __clone() {
        
    }

}
